﻿using SimpleInjector;
using Sustainalytics.AwsS3.Client;
using Sustainalytics.ClientDW.Entities;
using Sustainalytics.Controversies.BusinessLogic;
using Sustainalytics.DataLayer.Shared;
using Sustainalytics.Entities.ESGRatings;
using Sustainalytics.ESG.Entities;
using Sustainalytics.ESGRatings.BusinessLogic.ESGOnlineReport;
using Sustainalytics.MongoDB.Extensions;
using System.Web.Http;
using Sustainalytics.Utils.Configuration;
using Sustainalytics.Controversies.Service.BlInvoker;
using Sustainalytics.Utils.Serilog;

namespace Sustainalytics.Controversies.Service
{
    public static class CompositionRoot
    {
        private static Container container;

        public static Container GetContainer()
        {
            return container;
        }

        public static Container RegisterDependencies(HttpConfiguration config)
        {
            container = new Container();

            container.Options.DefaultScopedLifestyle = new SimpleInjector.Lifestyles.AsyncScopedLifestyle();
            container.RegisterWebApiControllers(config);

            var accessKey = SettingsHelper.Read("accesKeyId", "AKIAJKGZZMOFAVOVLHJA");
            var secretAccessKey = SettingsHelper.Read("awsSecretKey", "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");
            var serviceEndPoint = SettingsHelper.Read("s3ServiceEndPoint", "https://s3-eu-west-1.amazonaws.com/");

            container.RegisterMisc(accessKey, secretAccessKey, serviceEndPoint);

            container.RegisterRepositories();

            container.RegisterCollections();

            container.RegisterBussinessLogic();

            container.Verify();
            return container;
        }

        private static void RegisterCollections(this Container container)
        {
            container.Register(() => MongoFactory.GetCollectionFromDatabase<CorporateData>(MongoFactory.GetConnectionStrings().ClientDW));
            container.Register(() => MongoFactory.GetCollectionFromDatabase<RPControversyIndicator>(MongoFactory.GetConnectionStrings().ClientDW));
        }

        private static void RegisterRepositories(this Container container)
        {
            container.Register(typeof(IRepositoryCollection<SubPeerGroupKeyEsgIssue>), () => new RepositoryCollection<SubPeerGroupKeyEsgIssue>(MongoFactory.GetConnectionStrings().ClientDW));
            container.Register(typeof(IRepositoryCollection<Analyst>), () => new RepositoryCollection<Analyst>(MongoFactory.GetConnectionStrings().ClientDW));
            container.Register(typeof(IRepositoryCollection<IndicatorTemplate>), () => new RepositoryCollection<IndicatorTemplate>(MongoFactory.GetConnectionStrings().ClientDW));
            container.Register(typeof(IRepositoryCollection<CorporateData>), () => new RepositoryCollection<CorporateData>(MongoFactory.GetConnectionStrings().ClientDW));
            container.Register(typeof(IRepositoryCollection<FinancialData>), () => new RepositoryCollection<FinancialData>(MongoFactory.GetConnectionStrings().ClientDW));
            container.Register(typeof(IRepositoryCollection<RPCompanyProfile>), () => new RepositoryCollection<RPCompanyProfile>(MongoFactory.GetConnectionStrings().ClientDW));
            container.Register(typeof(IRepositoryCollection<RPCompanyESGComputationResult>), () => new RepositoryCollection<RPCompanyESGComputationResult>(MongoFactory.GetConnectionStrings().ClientDW));
            container.Register(typeof(IRepositoryCollection<CompanyHistoricalPerformance>), () => new RepositoryCollection<CompanyHistoricalPerformance>(MongoFactory.GetConnectionStrings().ClientDW));
            container.Register(typeof(IRepositoryCollection<RPIndicatorExtended>), () => new RepositoryCollection<RPIndicatorExtended>(MongoFactory.GetConnectionStrings().ClientDW));
            container.Register(typeof(IRepositoryCollection<RPControversyIndicator>), () => new RepositoryCollection<RPControversyIndicator>(MongoFactory.GetConnectionStrings().ClientDW));
            container.Register(typeof(IRepositoryCollection<ComparisonGroupControversy>), () => new RepositoryCollection<ComparisonGroupControversy>(MongoFactory.GetConnectionStrings().ClientDW));
            container.Register(typeof(IRepositoryCollection<EventIndicator>), () => new RepositoryCollection<EventIndicator>(MongoFactory.GetConnectionStrings().ClientDW));
            container.Register(typeof(IRepositoryCollection<Incident>), () => new RepositoryCollection<Incident>(MongoFactory.GetConnectionStrings().ClientDW));
            container.Register(typeof(IRepositoryCollection<CompanyKeyESGIssue>), () => new RepositoryCollection<CompanyKeyESGIssue>(MongoFactory.GetConnectionStrings().ClientDW));
            container.Register(typeof(IRepositoryCollection<Source>), () => new RepositoryCollection<Source>(MongoFactory.GetConnectionStrings().ClientDW));
            container.Register(typeof(IRepositoryCollection<ESGProfile>), () => new RepositoryCollection<ESGProfile>(MongoFactory.GetConnectionStrings().ClientDW));
        }

        private static void RegisterBussinessLogic(this Container container)
        {
            container.Register(typeof(IHistoricalDataBusinessLogicUnit), () => new HistoricalDataBusinessLogicUnit(container.GetInstance<IRepositoryCollection<CompanyHistoricalPerformance>>()));
            container.Register(() => PlainBlFactory.GetInstance<RPControversyIndicator>(MongoFactory.GetConnectionStrings().ClientDW));
            container.Register(() => PlainBlFactory.GetInstance<ComparisonGroupControversy>(MongoFactory.GetConnectionStrings().ClientDW));
            container.Register(() => PlainBlFactory.GetInstance<EventIndicator>(MongoFactory.GetConnectionStrings().ClientDW));
            container.Register(() => PlainBlFactory.GetInstance<Incident>(MongoFactory.GetConnectionStrings().ClientDW));
            container.Register(() => PlainBlFactory.GetInstance<CorporateData>(MongoFactory.GetConnectionStrings().ClientDW));
            container.Register(() => PlainBlFactory.GetInstance<IndicatorTemplate>(MongoFactory.GetConnectionStrings().ClientDW));
        }

        private static void RegisterMisc(this Container container, string accessKey, string secretAccessKey, string serviceEndPoint)

        {
            container.RegisterSingleton(typeof(IS3Client), () => new S3Client(new S3ClientSettings()
            {
                AccessKey = accessKey,
                SecretAccessKey = secretAccessKey,
                ServiceEndPoint = serviceEndPoint,
            }
            ));

            container.Register(() => MongoFactory.GetConnectionStrings());
            container.Register(typeof(IServiceBlInvoker), () => BlInvokerFactory.GetInstance());
            container.RegisterSingleton(typeof(ControversiesServiceSerilog), () => ControversiesServiceSerilog.Log);
        }
    }
}
